package skyblue;

import java.util.Vector;

public class Constraint {

	private Vector<Variable> variables;
	private Vector<Method> methods;
	private Strength strength;
	private Method selectedMethod;
	private Mark mark;
	//private boolean stayFlag;
	protected String constraintType;

	// Q execRootMethod used to back up the selected method
	private Method execrootmethod;

	public Constraint(Strength strength) {

		this.strength = strength;
		this.mark = new Mark(0);
		this.variables = new Vector<Variable>();
		this.methods = new Vector<Method>();
		
		this.selectedMethod = null;
		this.constraintType = null;
		//this.stayFlag = false;

	}

	public Constraint(Constraint constraint) {

		this.variables = constraint.getVariables();
		this.methods = constraint.getMethods();
		this.strength = constraint.getStrength();
		this.selectedMethod = constraint.getSelectedMethod();
		this.execrootmethod = constraint.getExecRootMethod();
		this.mark = constraint.getMark();
		this.constraintType = constraint.getConstraintType();
		//this.stayFlag = constraint.getStayFlag();
	}

	// inputsValid() returns true if all of the input variables for the
	// constraint are valid.
	// FM û�����壬���ǵ�inputs���ǿ�,�������ǵ�ִ�в���Ҫ���Ļ�����Ϣ
//	public boolean inputsValid() {
//
//		if (selectedMethod == null) {
//			return false;
//		}
//		Variable iter;
//		for (int i = 0; i < selectedMethod.getInputs().size(); i++) {
//			iter = (Variable) selectedMethod.getInputs().get(i);
//			if (!iter.isValid()) {
//				return false;
//			}
//		}
//		return true;
//	}

	// set the "determinbys" to all the variables of the output of the selected
	// method of the constraint
	public void determineVars() {

		if (this.selectedMethod == null) {
			return;
		}
		Variable iteri;
		for (int i = 0; i < selectedMethod.getOutputs().size(); i++) {
			iteri = (Variable) selectedMethod.getOutputs().get(i);
			// FM
			if (!iteri.getDeterminedbys().contains(this)) {
				iteri.getDeterminedbys().add(this);
			}
		}
	}

	public void enforce(Method selectedMethod) {
		this.selectedMethod = selectedMethod;
	}

	public void revoke() {
		this.selectedMethod = null;
	}

	public boolean enforced() {
		return this.selectedMethod == null ? false : true;
	}

	public void backupSelectedMethod() {
		this.execrootmethod = selectedMethod;
	}

	public boolean methedChanged() {
		return this.execrootmethod == this.selectedMethod ? false : true;
	}

//	public void clearStayFlag() {
//		sthis.stayFlag = false;
//	}

	// Gets and Sets
	public Vector<Variable> getVariables() {
		return variables;
	}

	public void setVariables(Vector<Variable> variables) {
		this.variables = variables;
	}

	public Strength getStrength() {
		return strength;
	}

	public void setStrength(Strength strength) {
		this.strength = strength;
	}

	public Method getSelectedMethod() {
		return selectedMethod;
	}

	public Method getExecRootMethod() {
		return execrootmethod;
	}

	public void setExecRootMethod(Method execRootMethod) {
		this.execrootmethod = execRootMethod;
	}

	public Mark getMark() {
		return mark;
	}

	public void setMark(Mark mark) {

		this.mark.setMyMark(mark.getMyMark());
	}

//	public boolean getStayFlag() {
//		return stayFlag;
//	}
//
//	public void setStayFlag() {
//		this.stayFlag = true;
//	}

	public void setSelectedMethod(Method selectedMethod) {
		this.selectedMethod = selectedMethod;
	}

//	public void setStayFlag(boolean stayFlag) {
//		this.stayFlag = stayFlag;
//	}

	public Vector<Method> getMethods() {
		return methods;
	}

	public void setMethods(Vector<Method> methods) {
		this.methods = methods;
	}

	public String getConstraintType() {
		return constraintType;
	}

	public void setConstraintType(String constraintType) {
		this.constraintType = constraintType;
	}

}
